﻿#pragma once

#include "Misc/EngineEditorMacros.h"
#include "Object/Object.h"
#include "Math/Vec2.h"
#include "Material/Material.h"
#include "MaterialGraphNodeModel.m.h"

class RMaterialGraphPinModel;
class RTexture2D;


RCLASS(ExtraHeader= [ "MaterialGraph/Pin/MaterialGraphPinModel.h" ])
class RMaterialGraphNodeModel : public RObject
{
    ROBJECT

public:
    //get all include files in shader code
    //for example : U"#include \"TestAdd.h\"\n";
    virtual CString GetIncludeFiles() 
    {
        return CString();
    }

    //for example : "output1=input1 + input2;"
    virtual CString GenerateExpression()     
    {
        return CString();
    }

    //LeftTop position in graph space
    RFIELD()
    SVec2 Position;

    int64_t GetOutputNum() const;
    TSharedObjectPtr<RMaterialGraphPinModel> GetOutput(int64_t Index) const;

    int64_t GetInputNum() const;
    TSharedObjectPtr<RMaterialGraphPinModel> GetInput(int64_t Index) const;

//输出节点相关：
    //是不是输出节点
    virtual bool IsOutputNode() const { return false; }
    //获取输出节点的着色器模板,只有输出节点需要重载这个函数
    virtual CString GetShaderTemplate() const { return CString(); }
    //获取输出节点的对应对的材质类型，只有输出节点需要重载这个函数
    virtual ERenderMaterialType GetMaterialType() const { return ERenderMaterialType::Unknow; }



//参数和纹理相关：
    //能不能转换成参数
    virtual bool CanConvertToParameter() const { return false; }
    //能不能改出参数
    virtual bool CanConvertFromParameter() const { return false; }

    //是不是参数节点
    virtual bool IsParameter() const { return false; }
    //获取参数名字
    virtual CString GetParameterName() const { return CString(); }
    //设置参数名字
    virtual void SetParameterName(const CString& InName) {}

    //收集参数和纹理
    //纹理有可能是个参数，所以需要在这里收集
    //只有和参数或者纹理有关的节点才需要重载这个函数
    virtual void CollectParameterAndTextures(
        TVector<float>& InOutFloatParameters  //浮点参数的默认值
        ,TVector<TSharedObjectPtr<RTexture2D>>& InOutTexture2Ds
        ,TMap<CString,SMaterialParameterDescription>& InOutParameterDescriptions
    ) 
    {};

protected:
    RFIELD()
    TVector<TSharedObjectPtr<RMaterialGraphPinModel>> Outputs;

    RFIELD()
    TVector<TSharedObjectPtr<RMaterialGraphPinModel>> Inputs;

public:


};

